#include "GUI.h"
#include "Frame.h"

#include "../../tools/Log.h"
#include "../../tools/xml/ticpp.h"
#include "../../draw/DrawSystem.h"

using namespace std;

GUI::GUI(const char* filename)
: frames()
, currentFrame(NULL)
, initialFrame("")
, doRollOvers(false)
, enabled(false) {
	if(strlen(filename) != 0) 
		load(filename);
}

GUI::~GUI() {
	kill();
}

void GUI::kill() {
	//Clear out all frames
	for(FrameList::iterator itr = frames.begin(); itr != frames.end(); itr++)
		delete itr->second;
	frames.clear();
}

bool GUI::load(const char* filename) {	
	using namespace ticpp;
	try {
		string val;
		Document doc( filename );
		doc.LoadFile();
		
		Node* node = doc.FirstChild();
		Element* elem = node->FirstChildElement();
		elem->GetValue(&val);
		if(val != "GUI")		//Ensure that the first child is of type "GUI"
			throw Exception("First element was not type GUI!");
		elem->GetAttribute("initialFrame", &initialFrame);
		elem->GetAttribute("rollovers", &doRollOvers);
		
		//Load each frame
		Node *child = NULL;
		while( (child = node->FirstChild()->IterateChildren( child )) != NULL) {
			string frameName;
			
			child->GetValue(&val);
			if(val != "Frame")
				throw Exception("GUI element was not a Frame");
				
			//preload frame name for insertion into the map
			child->ToElement()->GetAttribute("name", &frameName);
			
			Frame* newFrame = new Frame();
			frames[frameName] = newFrame;
			
			//load the frame
			newFrame->loadFromXML(child);
		}
	}
	catch( Exception& ex )	{
	    lout <<"WARNING: GUI - Error parsing \""<<filename<<"\": "<< ex.what()<<endl;
	    return false;
	}
	
	onWindowResize(DrawSystem::Instance().getFrameWidth(), DrawSystem::Instance().getFrameHeight());
	return true;
}

void GUI::enable() {
	switchToFrame(initialFrame);
}
void GUI::disable() {
	if(currentFrame == NULL) return;
	currentFrame->disable();
}

void GUI::onWindowResize(float width, float height) {	
	for(FrameList::iterator itr = frames.begin(); itr != frames.end(); itr++)
		itr->second->onWindowResize(width, height);
}

bool GUI::switchToFrame(const string& name) {
	FrameList::iterator itr = frames.find(name);
	if(itr == frames.end())
		return false;
		
	if(currentFrame != NULL)
		currentFrame->disable();
		
	currentFrame = itr->second;
	currentFrame->enable();
	return true;
}

bool GUI::onMouseButtonDown(KEY_TYPE button, int X, int Y) {
	if(currentFrame == NULL) return false;
	
	//Translate the click into frame coordinates
	float windowWidth = DrawSystem::Instance().getWindowWidth();
	float windowHeight = DrawSystem::Instance().getWindowHeight();
	float frameWidth = DrawSystem::Instance().getFrameWidth();
	float frameHeight = DrawSystem::Instance().getFrameHeight();
	float x = float(X)/windowWidth * frameWidth;
	float y = float(Y)/windowHeight * frameHeight;
	
	if(button == MOUSE_BUTTON_LEFT)
		return currentFrame->leftClick(x, y);
	return false;
}
void GUI::onMouseButtonUp(KEY_TYPE , int, int) {
}
bool GUI::onKeyDown(KEY_TYPE b) {
	if(currentFrame == NULL) return false;
	
	return currentFrame->keyPress(b);
}
void GUI::onKeyUp(KEY_TYPE) {
}
void GUI::onMouseMove(int x, int y){
	if(doRollOvers && currentFrame != NULL)
		currentFrame->rollOver(x,y);
}


